package org.finesys.ai.core;

import okhttp3.OkHttpClient;
import retrofit2.Call;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

class RequestExecutor<Request, Response, ResponseContent>
        implements SyncOrAsyncOrStreaming<ResponseContent> {

    private final Call<Response> call;
    private final Function<Response, ResponseContent> responseContentExtractor;

    private final OkHttpClient okHttpClient;
    private final String endpointUrl;
    private final Supplier<Request> requestWithStreamSupplier;
    private final Class<Response> responseClass;
    private final Function<Response, ResponseContent> streamEventContentExtractor;
    private final boolean logStreamingResponses;

    /**
     * RequestExecutor 构造函数
     *
     * @param call                   用于发送HTTP请求的Call对象
     * @param responseContentExtractor 用于从响应中提取响应内容的函数
     * @param okHttpClient           用于发送HTTP请求的OkHttpClient对象
     * @param endpointUrl            请求的端点URL
     * @param requestWithStreamSupplier 提供带有流的请求的Supplier
     * @param responseClass          响应对象的类类型
     * @param streamEventContentExtractor 用于从响应中提取流事件内容的函数
     * @param logStreamingResponses  是否记录流式响应的标志
     */
    RequestExecutor(Call<Response> call,
                    Function<Response, ResponseContent> responseContentExtractor,

                    OkHttpClient okHttpClient,
                    String endpointUrl,
                    Supplier<Request> requestWithStreamSupplier,
                    Class<Response> responseClass,
                    Function<Response, ResponseContent> streamEventContentExtractor,
                    boolean logStreamingResponses
    ) {
        this.call = call;
        this.responseContentExtractor = responseContentExtractor;

        this.okHttpClient = okHttpClient;
        this.endpointUrl = endpointUrl;
        this.requestWithStreamSupplier = requestWithStreamSupplier;
        this.responseClass = responseClass;
        this.streamEventContentExtractor = streamEventContentExtractor;
        this.logStreamingResponses = logStreamingResponses;
    }

    /**
     * RequestExecutor类的构造函数。
     *
     * @param call                调用Retrofit库中的Call接口，用于执行HTTP请求。
     * @param responseContentExtractor 用于从Response中提取ResponseContent的函数式接口。
     */
    RequestExecutor(Call<Response> call, Function<Response, ResponseContent> responseContentExtractor) {
        this.call = call;
        this.responseContentExtractor = responseContentExtractor;

        this.okHttpClient = null;
        this.endpointUrl = null;
        this.requestWithStreamSupplier = null;
        this.responseClass = null;
        this.streamEventContentExtractor = null;
        this.logStreamingResponses = false;
    }

    /**
     * 执行请求并返回响应内容
     *
     * @return 返回响应内容对象
     */
    @Override
    public ResponseContent execute() {

        return new SyncRequestExecutor<>(call, responseContentExtractor).execute();
    }

    @Override
    public AsyncResponseHandling onResponse(Consumer<ResponseContent> responseHandler,Consumer<Throwable> errorHandler) {

        return new AsyncRequestExecutor<>(call, responseContentExtractor).onResponse(responseHandler);
    }

    @Override
    public StreamingResponseHandling onPartialResponse(Consumer<ResponseContent> partialResponseHandler) {

        return new StreamingRequestExecutor<>(
                okHttpClient,
                endpointUrl,
                requestWithStreamSupplier,
                responseClass,
                streamEventContentExtractor,
                logStreamingResponses
        ).onPartialResponse(partialResponseHandler);
    }
}